/*
 * ImageControler.h
 *
 *  Created on: 08.08.2012
 *      Author: Caffeine
 */

#ifndef IMAGECONTROLER_H_
#define IMAGECONTROLER_H_

#include <IReferenceCounted.h>
#include "ImageControlerRecord.h"
#include <thread/ITaskList.h>
#include <thread/IMutex.h>
#include "ITextureSlot.h"

namespace irr{
namespace image{

/**
 * @class ImageControler
 * Класс заведует динамической загрузкой и выгрузкой текстур
 */

class ImageControler: public irr::image::ITextureSlot {
private:
	irr::video::ITexture*texture;
	irr::video::IImage*image;
	irr::io::path path;
	irr::core::array<ImageControlerRecord*> list;
	irr::thread::IMutex*locked;
	irr::thread::IMutex*loaded;
protected:
	bool attach(irr::io::path p,irr::core::vector2di pos);
	bool attach(irr::video::IImage*i,irr::core::vector2di pos);
	bool attach(irr::video::ITexture*i,irr::core::vector2di pos);
	bool attach_origenal(irr::core::recti rect);
	void useLayout(irr::u32 index);
	void clearUsedLayout();
public:
	ImageControler();
	/***
	 * Конструктор. При создании так же указывается и тектура
	 *
	 * @param path путь к текстуре
	 */
	ImageControler(irr::io::path path);
	virtual ~ImageControler();

	/***
	 * Устанавливает путь к текстуре. Если На момент установки новой текстуры старая уже была загрежена
	 * то новую новая текстура тоже будет загружена. Если рисунок был изменён, то путь будет не верным
	 */
	void setPath(irr::io::path path);

	/***
	 * Возвращяет путь к текущей текстуре
	 */
	irr::io::path getPath();

	/***
	 * Загружает текстуру
	 */
	virtual void load();

	/***
	* Выгружает текстуру
	*/
	virtual void unload();
	bool isLoaded();

	/***
	 * Переводит текущую текстуру из оперотивной памяти в память грачиеской карты.
	 */
	void lock();

	/***
	 * Переводит текущую текстуру из памяти грачиеской карты в оперотивную память. Необходимо вызывать
	 * в том потоке, в котором создан IrrlichtDevice
	 */
	void unlock();
	bool isLocked();
	ImageControlerRecord*addLayout(irr::io::path="",irr::core::vector2di=irr::core::vector2di(0,0));
	irr::u32 addLayout(ImageControlerRecord*icr);
	ImageControlerRecord*getLayout(irr::u32 index);
	irr::s32 indexOfPath(irr::io::path p);

	/***
	 * Удаляет слой по его номеру
	 *
	 * @param index номер слоя
	 */
	void removeLayout(irr::u32 index);
	
	/***
	 * Удаляет слой по пути к файлу
	 *
	 * @param index номер слоя
	 */
	void removeLayout(irr::io::path p);

	/***
	* Возвращяет количество наложенных слоёв
	*
	* @return количество слоёв
	*/
	irr::u32 getLayoutCount();

	/***
	 * Накладывает все слои в умном режиме (если слой уже наложен,
	 * то повторного накладывания не произайдёт). Использовать можно только
	 * если текустура открта (unlock). Функцию можно выпонять не в основном потоке.
	 * Будет выполнятся в том потоке, который её вызвал
	 *
	 * см. lock(), unlock()
	 */
	void smartUseAllLayout();

	/***
	 * Накладывает все слои в умном режиме (если слой уже наложен,
	 * то повторного накладывания не произайдёт). Использовать можно только
	 * если текустура открта (unlock). Функцию можно выпонять не в основном потоке.
	 * Будет выполнятся в новом потоке. По окончанию работы вызовет указанную задачу
	 *
	 * см. lock(), unlock()
	 *
	 * @param done задача, которую нужно выполнить после окончания работы потока
	 */
	void smartUseAllLayout_unsync(irr::thread::ITask*done);
	
	virtual irr::video::ITexture*getTexture();
};

}//namespace image
}//namespace irr



#endif /* IMAGECONTROLER_H_ */
